package com.itheima.service.mongo.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.itheima.domain.db.*;
import com.itheima.service.mongo.MovementService;
import com.itheima.util.ConstantUtil;
import com.itheima.vo.MovementVo;
import com.itheima.vo.PageBeanVo;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.DubboService;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;

import java.util.ArrayList;
import java.util.List;

/**
 * @author zsk
 * @create 2022-03-17-16:33
 */
@DubboService
public class MovementServiceImpl implements MovementService {

    @Autowired
    private RedisIdService redisIdService;

    @Autowired
    private MongoTemplate mongoTemplate;


    //发表动态
    @Override
    public void saveMovement(Movement movement) {
        Long pid = redisIdService.getNextId(ConstantUtil.MOVEMENT_ID);
        movement.setPid(pid);
        // 1.保存动态详情
        mongoTemplate.save(movement);
        // 2.查询好友列表
        // 2-1  构建条件
        Query query = new Query(Criteria.where("userId").is(movement.getUserId()));
        // 2-2 mongo查询
        List<Friend> friendList = mongoTemplate.find(query, Friend.class);
        // 2-3 遍历
        if (CollectionUtil.isNotEmpty(friendList)) {
            for (Friend friend : friendList) {
                // 2-4 获取好友id
                Long friendId = friend.getFriendId();
                // 3. 向好友添加我的动态
                // 3-1 创建实体
                FriendMovement friendMovement = new FriendMovement();
                friendMovement.setUserId(movement.getUserId()); // 发布人id
                friendMovement.setPublishId(movement.getId()); // 动态id
                friendMovement.setCreated(movement.getCreated()); // 发布时间
                // 3-2 保存好友动态
                mongoTemplate.save(friendMovement, ConstantUtil.MOVEMENT_FRIEND+friendId);
            }
        }

    }

    //查询我的动态
    @Override
    public PageBeanVo findByMovementPage(Long userId, Integer pageNum, Integer pageSize) {

        //创建索引
        Integer index = (pageNum-1) * pageSize;

        //构建查询条件
        Query query = new Query(
                Criteria.where("userId").is(userId)//userId
                .and("state").is(1))//state必须为1
                .with(Sort.by(Sort.Order.desc("created")))//按发布时间排序
                .skip(index).limit(pageSize);//查询第一页十条数据

        //查询
        List<Movement> movementList = mongoTemplate.find(query, Movement.class);
        //查询总记录数
        long counts = mongoTemplate.count(query, Movement.class);
        //返回结果
        return new PageBeanVo(pageNum, pageSize, counts, movementList);
    }

    //查询好友动态
    @Override
    public PageBeanVo findByFriendMovement(Long userId, Integer pageNum, Integer pageSize) {
        Integer index = (pageNum - 1) * pageSize;
        //构建查询条件
        Query query = new Query()
                .with(Sort.by(Sort.Order.desc("created")))//按照发布时间降序
                .skip(index).limit(pageSize);//分页

        //查询
        List<FriendMovement> friendMovementList = mongoTemplate.find(query, FriendMovement.class,
                ConstantUtil.MOVEMENT_FRIEND + userId);

        //创建一个集合存储动态信息
        List<Movement> movementList = new ArrayList<>();
        
        //非空判断
        if (CollectionUtil.isNotEmpty(friendMovementList)){
            for (FriendMovement friendMovement : friendMovementList) {
                //根据publishId查询好友动态
                ObjectId publishId = friendMovement.getPublishId();
                Movement movement = mongoTemplate.findById(publishId, Movement.class);

                //返回状态
                if (movement.getState() == 1){
                    movementList.add(movement);
                }

            }
        }

        //返回结果
        return new PageBeanVo(pageNum,pageSize,0L,movementList);
    }

    //查询推荐动态
    @Override
    public PageBeanVo findRecommendMovementByPage(Long userId, Integer pageNum, Integer pageSize) {

        Integer index = (pageNum -1) * pageSize;

        //构建查询条件
        Query query = new Query(
                Criteria.where("userId").is(userId))//条件
                .with(Sort.by(Sort.Order.desc("created")))//排序
                .skip(index).limit(pageSize);

        //查询
        List<RecommendMovement> recommendMovementList = mongoTemplate.find(query, RecommendMovement.class);

        //创建一个存储Movement对象的集合
        List<Movement> movementList = new ArrayList<>();

        //非空判断后遍历
        if (CollectionUtil.isNotEmpty(recommendMovementList)){
            for (RecommendMovement recommendMovement : recommendMovementList) {

                //获取动态id
                ObjectId publishId = recommendMovement.getPublishId();

                //去对应的动态表中查询
                Movement movement = mongoTemplate.findById(publishId, Movement.class);

                //存储到集合中
                movementList.add(movement);
            }
        }

        //返回结果
        return new PageBeanVo(pageNum,pageSize,0L,movementList);
    }

    //根据publishId查询动态详情
    @Override
    public Movement findById(ObjectId id) {
        return mongoTemplate.findById(id,Movement.class);
    }

    //设置访问记录
    @Override
    public void saveVisitor(Visitor visitor) {
        mongoTemplate.save(visitor);
    }

    //后台分页查询动态列表
    @Override
    public PageBeanVo findMovementByPage(Long userId, Integer state, Integer pageNum, Integer pageSize) {

        //构建查询条件
        Query query = new Query()
                .with(Sort.by(Sort.Order.desc("created")))//按照发布时间降序
                .skip((pageNum - 1) * pageSize).limit(pageSize);
        //动态条件
        if (userId != null){
            query.addCriteria(Criteria.where("userId").is(userId));
        }
        if (state != null){
            query.addCriteria(Criteria.where("state").is(state));
        }

        //查询
        List<Movement> movementList = mongoTemplate.find(query, Movement.class);

        //查询总记录数
        long count = mongoTemplate.count(query,Movement.class);

        //返回分页对象
        return new PageBeanVo(pageNum,pageSize,count,movementList);
    }

    //更新动态信息
    @Override
    public void update(Movement movement) {
        mongoTemplate.save(movement);
    }
}
